package com.softeem.mpdemo.controller;

import cn.hutool.core.util.DesensitizedUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.crypto.SecureUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.xiaoymin.knife4j.annotations.ApiSort;
import com.github.xiaoymin.knife4j.annotations.ApiSupport;
import com.softeem.mpdemo.dto.Result;
import com.softeem.mpdemo.entity.Admin;
import com.softeem.mpdemo.service.AdminService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Objects;

@CrossOrigin  //允许来自所有源的请求
@Tag(name = "管理员管理", description = "对于管理员的相关访问操作，如：登录，添加，信息更新，列表查询，删除等")
@RestController
public class AdminController {

    @Autowired
    private AdminService adminService;

    /**
     * Post&Get
     * 登录
     *
     * @param admin
     * @return
     */
    @Operation(summary = "管理员登录", description = "需要提供管理员的账号和密码信息")
    @PostMapping("/admin/login")
    public Result login(@Parameter(description = "管理员对象") @RequestBody Admin admin) {
        return adminService.login(admin);
    }

    /**
     * 注册
     *
     * @param admin
     * @return
     */
    @Operation(summary = "管理员添加", description = "至少需要提供账号和密码信息")
    @PostMapping("/admin/reg")
    public Result reg(@Parameter(description = "管理员对象") @RequestBody Admin admin) {
        return adminService.reg(admin);
    }

    /**
     * 管理员信息修改
     *
     * @param admin
     * @return
     */
    @Operation(summary = "管理员信息更新", description = "根据id修改密码或状态，id必须提供")
    @PutMapping("/admin/update")
    public Result modify(@Parameter(description = "管理员对象") @RequestBody Admin admin) {
        //判断是否需要修改密码
        if (Objects.nonNull(admin.getPassword())) {
            //生成盐
            String salt = RandomUtil.randomString(6);
            //使用盐和输入密码加密
            String pwd = SecureUtil.md5(admin.getPassword() + salt);
            //将新密码和随机盐添加到对象中
            admin.setPassword(pwd);
            admin.setSalt(salt);
        }
        //执行修改（根据id修改）
        if (adminService.updateById(admin)) {
            return Result.ok().setMsg("修改成功").setData(admin);
        }
        return Result.fail().setMsg("更新失败");
    }

    /**
     * 管理员列表   132****345（脱敏）
     *
     * @return
     */
    @Operation(summary = "查询所有管理员", description = "显示所有管理员信息，其中密码随机盐做脱敏处理")
    @GetMapping("/admin/listAll")
    public Result selectAll() {
        //查询所有管理员
        List<Admin> list = adminService.list();
        if (list.isEmpty()) {
            return Result.fail().setMsg("无记录");
        }
        list.forEach(admin -> {
            //取出密码、盐脱敏后重新填充到密码属性中
            admin.setPassword(DesensitizedUtil.password(admin.getPassword()));
            admin.setSalt(DesensitizedUtil.password(admin.getSalt()));
        });
        return Result.ok().setMsg("查询成功").setData(list);
    }

    /**
     * 分页查询
     *
     * @param page  当前显示的页码数
     * @param limit 每页数据条目数
     * @return
     */
    @Operation(summary = "分页查询管理员", description = "显示所有管理员信息，其中密码随机盐做脱敏处理")
    @Parameters({  //参数集
            @Parameter(name = "page", description = "当前页", required = true),
            @Parameter(name = "limit", description = "每页数据条目数", required = true)
    })
    @GetMapping("/admin/list")
    public Result list(@RequestParam(defaultValue = "1") Integer page, @RequestParam(defaultValue = "5") Integer limit) {
        //执行分页查询
        List<Admin> list = adminService.list(new Page<>(page, limit));
        if (list.isEmpty()) {
            return Result.fail().setMsg("无记录");
        }
        list.forEach(admin -> {
            //取出密码、盐脱敏后重新填充到密码属性中
            admin.setPassword(DesensitizedUtil.password(admin.getPassword()));
            admin.setSalt(DesensitizedUtil.password(admin.getSalt()));
        });
        //查询总记录数
        long count = adminService.count();
        return Result.ok().setMsg("查询成功").setData(list).setCount((int) count);
    }

    /**
     * 根据id删除管理员(物理删除：谨慎操作)
     *
     * @param id
     * @return
     */
    @Operation(summary = "根据id删除管理员", description = "物理删除，需要提供管理员id，谨慎操作")
    @DeleteMapping("/admin/{id}")
    public Result delById(@Parameter(description = "管理员id", required = true) @PathVariable("id") Integer id) {
        Admin admin = adminService.getById(id);
        if (Objects.isNull(admin)) {
            return Result.fail().setMsg("该管理员不存在或者已经被删除!");
        }
        if (adminService.removeById(id)) {
            return Result.ok().setMsg("删除成功").setData(admin);
        }
        return Result.fail().setMsg("删除失败");
    }

}
